﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Surface.Core;

namespace Sublimation
{
    public class PreviewTower : MenuItemSurf
    {

        #region properties

        protected Tower curTower;
        public Tower CurTower
        {
            set 
            { 
                curTower = value;
                if (curTower != null)
                {
                    for (int i = 0; i < slotUpgradeList.Length; i++)
                    {
                        UpgradeNode aNode;
                        UpgradeNode newNode;

                        if (i > 1)
                        {
                            aNode = UpgradeTree.FindUpgrade(UpgradeTree.UpgradeRoot, curTower.Slots[i].Kind);
                            newNode = new UpgradeNode(worldProperties, aNode.Kind, aNode.Name, aNode.Description, aNode.Sprite, slotCenterList[(numberOfSlots - 1) - ((i - 2) * 3) - 1], aNode.ChildUpgrades);
                        }
                        else if (i == 0)
                        {
                            aNode = UpgradeTree.FindUpgrade(UpgradeTree.MainWeaponNode, curTower.Slots[i].Kind);
                            newNode = new UpgradeNode(worldProperties, aNode.Kind, aNode.Name, aNode.Description, aNode.Sprite, upgradeCenterList[i], aNode.ChildUpgrades);
                        }
                        else if (i == 1)
                        {
                            aNode = UpgradeTree.FindUpgrade(UpgradeTree.EnergyTransferNode, curTower.Slots[i].Kind);
                            newNode = new UpgradeNode(worldProperties, aNode.Kind, aNode.Name, aNode.Description, aNode.Sprite, upgradeCenterList[i], aNode.ChildUpgrades);
                        }
                        else
                        {
                            aNode = UpgradeTree.FindUpgrade(UpgradeTree.UpgradeRoot, curTower.Slots[i].Kind);
                            newNode = new UpgradeNode(worldProperties, aNode.Kind, aNode.Name, aNode.Description, aNode.Sprite, upgradeCenterList[i], aNode.ChildUpgrades);
                        }
                        newNode.Visible = true;
                        UpgradeNode oldNode = slotUpgradeList[i];
                        if (oldNode != null)
                        {
                            oldNode.Kill();
                            oldNode = null;
                        }
                        slotUpgradeList[i] = newNode;
                    }
                }
            }
            get { return curTower; }
        }

        // Textures
        protected Texture2D background;
        protected Texture2D slotBorders;
        protected Texture2D energyIcon;
        protected Texture2D emptyBackground;
        protected Texture2D backButton;
        protected Texture2D backButtonClicked;
        protected Texture2D backButtonTexture;
        protected Texture2D borderSlot0;
        protected Texture2D borderSlot0Select;
        protected Texture2D borderSlot1Select;
        protected Texture2D borderSlot1;
        protected Texture2D borderSlot2;
        protected Texture2D borderSlot3;
        protected Texture2D borderSlot4;
        protected Texture2D borderSlot5;

        protected Vector2 backButtonPos;
        protected Vector2 backButtonCenter;

        float completionPercentage;

        protected const float innerRadius = 75;
        protected const float slotCenterRadius = 100;
        protected const float outerRadius = 125;
        protected const int numberOfSlots = 12;

        protected Vector2[] slotCenterList; // center pos of the each upgrade icon displayed
        protected Vector2[] upgradeCenterList; // positions for current upgrades in slots inside inner circle
        protected List<Texture2D> quadrantTextureList = new List<Texture2D>();
        protected Vector2[] quadrantPosList; // position of the 4 quadrants
        protected Vector2[] collisionCircles;
        protected const float colcircleRadius = (innerRadius / 2) - 7.5f;

        protected int selectedSlotIndex; // ranges from 0 to 5 

        protected UpgradeNode[,] availableUpgrades;

        protected UpgradeNode[] slotUpgradeList;
        protected bool[] slotActivated;
        protected Vector2 selectedSlotPos = Vector2.Zero;
        protected float pieAngle;

        protected UpgradeNode draggedItem;
        protected UpgradeNode draggedDeleteItem;
        protected Contact dragDeleteItemContact;
        protected int draggedItemSlot;

        protected DescriptionItem descriptionItem;

        protected Vector2 dragItemPrePos;
        public Vector2 DragItemPos
        {
            set { dragItemPrePos = value; }
            get { return dragItemPrePos; }
        }
        protected Contact dragItemContact;
        public Contact DragItemContact
        {
            set { dragItemContact = value; }
            get { return dragItemContact; }
        }
        protected bool itemDragged = false;
        protected bool itemDeleteDragged = false;

        protected UpgradeTree upgradeTree;
        public UpgradeTree UpgradeTree
        {
            set { upgradeTree = value; }
            get { return upgradeTree; }
        }

        protected Color quadColor;
        public Color QuadColor
        {
            set { quadColor = value; }
            get { return quadColor; }
        }

        #endregion

        public PreviewTower(WorldProperties worldProperties,GameObject parent,Vector2 position,Vector2 origin,float rotation,Tower aTower)
            :base(worldProperties,parent,position,origin)
        {
            this.parent = parent;
            this.rotation = rotation;
            curTower = aTower;
            quadColor = Color.White;

            center = new Vector2(position.X + outerRadius , position.Y + outerRadius);
            slotCenterList = new Vector2[numberOfSlots];
            upgradeCenterList = new Vector2[numberOfSlots / 2];
            pieAngle = MathHelper.ToRadians(360 / numberOfSlots);

            // generate upgrade tree
            upgradeTree = new UpgradeTree(worldProperties);

            // create description Item (pass previewTower's parent to have to rotate around it)
            descriptionItem = new DescriptionItem(worldProperties, parent, "", this.Position);
            descriptionItem.Visible = false;


            quadrantPosList = new Vector2[6];
            quadrantPosList[0] = new Vector2(Position.X, Position.Y);
            quadrantPosList[1] = new Vector2(Position.X, Position.Y + outerRadius);
            quadrantPosList[2] = new Vector2(Position.X + outerRadius, Position.Y + outerRadius); // slot 2
            quadrantPosList[3] = new Vector2(Position.X, Position.Y + outerRadius); // slot 3
            quadrantPosList[4] = new Vector2(Position.X, Position.Y); ; // slot 4
            quadrantPosList[5] = new Vector2(Position.X + outerRadius, Position.Y); // slot 5

            if (Rotation != 0.0f)
            {
                for (int i = 0; i < quadrantPosList.Length; i++)
                {
                    quadrantPosList[i] = RotatePoint(parent.Position, rotation, quadrantPosList[i]);
                }
            }

            availableUpgrades = new UpgradeNode[6,3];

            slotActivated = new bool[6];
            for (int i = 0; i < slotActivated.Length; i++)
            {
                slotActivated[i] = false;
            }

            CalculateSlotCenters();
            CalculateUpgradeCenters();
            selectedSlotIndex = -1; // to denote none of the slots is selected

            slotUpgradeList = new UpgradeNode[6]; // for each quadrant and 2 semi circles


            // Initialize the upgrades array
            if (curTower != null)
            {
                for (int i = 0; i < slotUpgradeList.Length; i++)
                {
                    
                        UpgradeNode aNode;
                        UpgradeNode newNode;
                        if (i > 1)
                        {
                            aNode = UpgradeTree.FindUpgrade(UpgradeTree.UpgradeRoot, curTower.Slots[i].Kind);
                            newNode = new UpgradeNode(worldProperties, aNode.Kind, aNode.Name, aNode.Description, aNode.Sprite, slotCenterList[(numberOfSlots - 1) - ((i - 2) * 3) - 1], aNode.ChildUpgrades);
                        }
                        else if(i==0)
                        {
                            aNode = UpgradeTree.FindUpgrade(UpgradeTree.MainWeaponNode, curTower.Slots[i].Kind);
                            newNode = new UpgradeNode(worldProperties, aNode.Kind, aNode.Name, aNode.Description, aNode.Sprite, upgradeCenterList[i], aNode.ChildUpgrades);
                        }
                        else
                        {
                            aNode = UpgradeTree.FindUpgrade(UpgradeTree.EnergyTransferNode, curTower.Slots[i].Kind);
                            newNode = new UpgradeNode(worldProperties, aNode.Kind, aNode.Name, aNode.Description, aNode.Sprite, upgradeCenterList[i], aNode.ChildUpgrades);
                        }
                        if (selectedSlotIndex != -1)
                        {
                            newNode.Visible = true;
                        }
                        UpgradeNode oldNode = slotUpgradeList[i];
                        if (oldNode != null)
                        {
                            oldNode.Kill();
                            oldNode = null;
                        }
                        slotUpgradeList[i] = newNode;
                }
            }

            collisionCircles = new Vector2[6];

            collisionCircles[0] = new Vector2(center.X + colcircleRadius, center.Y + colcircleRadius); // for slot2
            collisionCircles[1] = new Vector2(center.X - colcircleRadius, center.Y + colcircleRadius);
            collisionCircles[2] = new Vector2(center.X - colcircleRadius, center.Y - colcircleRadius);
            collisionCircles[3] = new Vector2(center.X + colcircleRadius, center.Y - colcircleRadius);

            // additional collision circles that are used only in slot 0 and slot1 's deletion drags
            collisionCircles[4] = new Vector2(center.X, center.Y - (innerRadius / 2));
            collisionCircles[5] = new Vector2(center.X, center.Y + (innerRadius / 2));

            if (Rotation != 0.0f)
            {
                for(int i = 0 ; i < collisionCircles.Length; i++)
                    collisionCircles[i] = RotatePoint(parent.Position, deltaRotation, collisionCircles[i]);
            }

            backButtonPos = new Vector2(center.X + innerRadius + 25, center.Y + innerRadius + 5);
            backButtonCenter = backButtonPos + new Vector2(backButtonTexture.Width / 2, backButtonTexture.Height / 2);
            if (Rotation != 0.0f)
            {
                backButtonPos = RotatePoint(parent.Position, deltaRotation, backButtonPos);
                backButtonCenter = RotatePoint(parent.Position, deltaRotation, backButtonCenter);
            }
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            emptyBackground = Game.Content.Load<Texture2D>("Sprites/emptyBackground");
            background = Game.Content.Load<Texture2D>("Sprites/background_slot");
            energyIcon = Game.Content.Load<Texture2D>("Sprites/SlotSelect/energy_1");
            slotBorders = Game.Content.Load<Texture2D>("Sprites/SlotSelect/border_slot");
            
            backButton = Game.Content.Load<Texture2D>("Sprites/SlotSelect/backMenu");
            backButtonClicked = Game.Content.Load<Texture2D>("Sprites/SlotSelect/backMenuClicked");
            backButtonTexture = backButton;
            borderSlot0 = Game.Content.Load<Texture2D>("Sprites/SlotSelect/border_slot_0");
            borderSlot1 = Game.Content.Load<Texture2D>("Sprites/SlotSelect/border_slot_1");
            borderSlot2 = Game.Content.Load<Texture2D>("Sprites/SlotSelect/border_slot_2");
            borderSlot3 = Game.Content.Load<Texture2D>("Sprites/SlotSelect/border_slot_3");
            borderSlot4 = Game.Content.Load<Texture2D>("Sprites/SlotSelect/border_slot_4");
            borderSlot5 = Game.Content.Load<Texture2D>("Sprites/SlotSelect/border_slot_5");

            quadrantTextureList.Add(Game.Content.Load<Texture2D>("Sprites/SlotSelect/slot0"));
            quadrantTextureList.Add(Game.Content.Load<Texture2D>("Sprites/SlotSelect/slot1"));
            quadrantTextureList.Add(Game.Content.Load<Texture2D>("Sprites/SlotSelect/slot2"));
            quadrantTextureList.Add(Game.Content.Load<Texture2D>("Sprites/SlotSelect/slot3"));
            quadrantTextureList.Add(Game.Content.Load<Texture2D>("Sprites/SlotSelect/slot4"));
            quadrantTextureList.Add(Game.Content.Load<Texture2D>("Sprites/SlotSelect/slot5"));
            
            Sprite = background;
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            if (selectedSlotIndex == -1)
            {
                spriteBatch.Draw(slotBorders, Position, null, new Color(255,255,255,125), Rotation, Origin, 1.0f, SpriteEffects.None, 1.0f);
                Sprite = background;
            }
            else
            {
                Sprite = emptyBackground;

                if(selectedSlotIndex != -1)
                {
                    if (curTower != null)
                    {
                        spriteBatch.Draw(quadrantTextureList.ElementAt(selectedSlotIndex), quadrantPosList.ElementAt(selectedSlotIndex)
                            , null, QuadColor ,Rotation, Origin, 1.0f, SpriteEffects.None, 1.0f);

                        spriteBatch.Draw(backButtonTexture, backButtonPos
                            , null, Color.White, Rotation, Origin, 1.0f, SpriteEffects.None, 1.0f);
                    }
                }
            }
            spriteBatch.End();
        }

        public void CalculateSlotCenters()
        {
            float x = (float)(center.X + (slotCenterRadius) * Math.Cos(pieAngle/2));
            float y = (float)(center.Y + (slotCenterRadius)* Math.Sin(pieAngle/2));

            Vector2 slot1 = new Vector2((float)Math.Round(x,MidpointRounding.AwayFromZero),(float)Math.Round(y,MidpointRounding.AwayFromZero));
            slotCenterList[numberOfSlots - 1] = slot1;
            if (Rotation != 0.0f)
            {
                slotCenterList[11] = RotatePoint(parent.Position, deltaRotation, slotCenterList[11]);
            }

            Vector2 tempPos = slot1;
            for (int i = numberOfSlots - 2; i > -1; i--)
            {
                tempPos = RotatePoint(center  , pieAngle, tempPos);
                slotCenterList[i] = tempPos;
                if (Rotation != 0.0f)
                {
                    slotCenterList[i] = RotatePoint(parent.Position, deltaRotation, slotCenterList[i]);
                }
            }
        }

        public void CalculateUpgradeCenters()
        {
            float rotateRadian = MathHelper.ToRadians(45);
            float x = (float)(center.X + (innerRadius / 2) * Math.Cos(rotateRadian));
            float y = (float)(center.Y + (innerRadius / 2) * Math.Sin(rotateRadian));

            Vector2 slot2 = new Vector2((float)Math.Round(x, MidpointRounding.AwayFromZero), (float)Math.Round(y, MidpointRounding.AwayFromZero));
            upgradeCenterList[2] = slot2;

            Vector2 slot1 = slot2;
            slot1 = RotatePoint(center, rotateRadian, slot1);
            upgradeCenterList[1] = slot1;

            Vector2 slot3 = slot1;
            slot3 = RotatePoint(center, rotateRadian, slot3);
            upgradeCenterList[3] = slot3;

            Vector2 slot4 = slot3;
            slot4 = RotatePoint(center, rotateRadian * 2, slot4);
            upgradeCenterList[4] = slot4;

            Vector2 slot0 = slot4;
            slot0 = RotatePoint(center, rotateRadian , slot0);
            upgradeCenterList[0] = slot0;

            Vector2 slot5 = slot0;
            slot5 = RotatePoint(center, rotateRadian, slot5);
            upgradeCenterList[5] = slot5;

            if (Rotation != 0.0f)
            {
                for (int i = 0; i < upgradeCenterList.Length; i++ )
                    upgradeCenterList[i] = RotatePoint(parent.Position, deltaRotation, upgradeCenterList[i]);
            }

        }

        public void HasContact(Contact contact)
        {
            Vector2 contactPoint = new Vector2(contact.CenterX, contact.CenterY);

            // translate upgrades that are being dragged
            DragUpgrades(contactPoint, contact);
            DragDeleteUpgrade(contactPoint, contact);

            float disToCenter = Vector2.Distance(contactPoint, Center);

            Vector2 unrotatedCenter = center;
            float curRotation = this.Rotation % MathHelper.TwoPi;

            // if the item is rotated
            if (curRotation != 0)
            {
                // calculate the unrotated positions
                contactPoint = RotatePoint(parent.Position, MathHelper.TwoPi - curRotation, contactPoint);
                unrotatedCenter = RotatePoint(parent.Position, MathHelper.TwoPi - curRotation, unrotatedCenter);
            }

            Vector2 diff = new Vector2(contactPoint.X - unrotatedCenter.X, contactPoint.Y - unrotatedCenter.Y);
            Vector2 absDiff = new Vector2(Math.Abs(contactPoint.X - unrotatedCenter.X), Math.Abs(contactPoint.Y - unrotatedCenter.Y));

            // calculate the angle that the line between center and contact point makes
            float angle = 0;
            if (absDiff.X != 0)
            {
                angle = (float)Math.Atan(absDiff.Y / absDiff.X);
            }

            if (disToCenter <= outerRadius)
            {
                // inner circle
                if (disToCenter <= innerRadius)
                {
                    if (diff.Y > 0)
                    {
                        // lower semi-circle
                        
                        int slotIndex = 1;
                        if (!itemDragged && (selectedSlotIndex == -1 || selectedSlotIndex == slotIndex))
                        {
                            /*
                            // Disable the slot for upgrades 
                            GetAvailableUpgrades(UpgradeTree.EnergyTransferNode,slotIndex);
                            SetUpgradePositions(slotIndex);
                            // if the slot is upgradable, change the view
                            if (HasAvailableUpgrades(slotIndex))
                            {
                                selectedSlotIndex = slotIndex;
                                UpgradeTree.SelectedSlot = slotIndex;
                            }
                            */
                            /*
                            if (!itemDeleteDragged)
                            {
                                if ((slotActivated[selectedSlotIndex]))
                                    StartDeleteDrag(contact, selectedSlotIndex);
                            }
                             */
                        }

                        #region PART FOR DELETION DRAG
                        // on right side of semi circle
                        if (diff.X > 0)
                        {
                            // check for upgrade deletion start
                            if (selectedSlotIndex == 2 && !itemDeleteDragged && !itemDragged)
                            {
                                if ((slotActivated[selectedSlotIndex]))
                                    StartDeleteDrag(contact, selectedSlotIndex);
                            }
                        }
                        else if (diff.X < 0)
                        {
                            // check for upgrade deletion start
                            if (selectedSlotIndex == 3 && !itemDeleteDragged && !itemDragged)
                            {
                                if((slotActivated[selectedSlotIndex]))
                                    StartDeleteDrag(contact, selectedSlotIndex);
                            }
                        }
                        #endregion

                        //SetActivated(selectedSlotIndex);
                    }
                    else
                    {
                        int slotIndex = 0;
                        if (!itemDragged && (selectedSlotIndex == -1 || selectedSlotIndex == slotIndex))
                        {
                            /* Disable slot upgrade
                            // search in main weapon tree
                             GetAvailableUpgrades(UpgradeTree.MainWeaponNode,slotIndex);
                             SetUpgradePositions(slotIndex);
                             // if the slot is upgradable, change the view
                             if (HasAvailableUpgrades(slotIndex))
                             {
                                selectedSlotIndex = slotIndex;
                                UpgradeTree.SelectedSlot = slotIndex;
                             }
                            */
                            /* Disabled Delete for main weapons
                             if (!itemDeleteDragged)
                             {
                                 if ((slotActivated[selectedSlotIndex]))
                                     StartDeleteDrag(contact, selectedSlotIndex);
                             }
                             */
                        }

                        #region PART FOR DELETION DRAG
                        // on right side of semi circle
                        if (diff.X > 0)
                        {
                            // check for upgrade deletion start
                            if (selectedSlotIndex == 5 && !itemDeleteDragged && !itemDragged)
                            {
                                StartDeleteDrag(contact, selectedSlotIndex);
                            }
                        } // on left side of semi circle
                        else if (diff.X < 0)
                        {
                            // check for upgrade deletion start
                            if (selectedSlotIndex == 4 && !itemDeleteDragged && !itemDragged)
                            {
                                StartDeleteDrag(contact, selectedSlotIndex);
                            }
                        }
                        #endregion

                        //SetActivated(selectedSlotIndex);
                    }
                }

                else // outer circle 
                {
                    if (diff.X > 0)
                    {
                        /* Slot 2 : Lower Right Quadrant*/
                        if (diff.Y > 0)
                        {
                            int slotIndex = 2;
                            if (!itemDragged && !itemDeleteDragged && (selectedSlotIndex == -1 || selectedSlotIndex == slotIndex))
                            {

                                GetAvailableUpgrades(UpgradeTree.UpgradeRoot,slotIndex);
                                SetUpgradePositions(slotIndex);
                                // if the slot is upgradable, change the view
                                if (HasAvailableUpgrades(slotIndex))
                                {
                                    selectedSlotIndex = slotIndex;
                                    UpgradeTree.SelectedSlot = slotIndex;

                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        // lower right quadrant
                                        if (angle < pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[11];
                                            StartDrag(contact, selectedSlotIndex, 0);
                                        }
                                        else if (angle > pieAngle && angle < 2 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[10];
                                            StartDrag(contact, selectedSlotIndex, 1);
                                        }
                                        else if (angle > 2 * pieAngle && angle < 3 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[9];
                                            StartDrag(contact, selectedSlotIndex, 2);
                                        }
                                    }

                                    // set it activated for next time
                                    SetActivated(selectedSlotIndex);
                                }
                            }

                            #region PART FOR SLOT 1 UPGRADE DRAGS
                            else if (selectedSlotIndex == 1 && !itemDragged && !itemDeleteDragged)
                            {
                                // on right side of semi circle
                                if (diff.X > 0)
                                {
                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        StartDrag(contact, 1, 1);
                                    }
                                }
                            }
                            #endregion
                        }
                        else
                        {
                            int slotIndex = 5;
                            if (!itemDragged && !itemDeleteDragged && (selectedSlotIndex == -1 || selectedSlotIndex == slotIndex))
                            {

                                GetAvailableUpgrades(UpgradeTree.UpgradeRoot,slotIndex);
                                SetUpgradePositions(slotIndex);
                                // if the slot is upgradable, change the view
                                if (HasAvailableUpgrades(slotIndex))
                                {
                                    selectedSlotIndex = slotIndex;
                                    UpgradeTree.SelectedSlot = slotIndex;

                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        // upper right quadrant
                                        if (angle < pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[0];
                                            StartDrag(contact, selectedSlotIndex, 2);
                                        }
                                        else if (angle > pieAngle && angle < 2 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[1];
                                            StartDrag(contact, selectedSlotIndex, 1);
                                        }
                                        else if (angle > 2 * pieAngle && angle < 3 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[2];
                                            StartDrag(contact, selectedSlotIndex, 0);
                                        }
                                    }

                                    SetActivated(selectedSlotIndex);
                                }
                            }

                            #region PART FOR SLOT 0 UPGRADE DRAGS
                            else if (selectedSlotIndex == 0 && !itemDragged && !itemDeleteDragged)
                            {
                                if (diff.X > 0)
                                {
                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        StartDrag(contact, 0, 0);
                                    }
                                }
                            }
                            #endregion
                        }
                    }
                    else
                    {
                        if (diff.Y > 0)
                        {
                            int slotIndex = 3;
                            if (!itemDragged && !itemDeleteDragged && (selectedSlotIndex == -1 || selectedSlotIndex == slotIndex))
                            {

                                GetAvailableUpgrades(UpgradeTree.UpgradeRoot,slotIndex);
                                SetUpgradePositions(slotIndex);
                                // if the slot is upgradable, change the view
                                if (HasAvailableUpgrades(slotIndex))
                                {
                                    selectedSlotIndex = slotIndex;
                                    UpgradeTree.SelectedSlot = slotIndex;

                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        // lower left quadrant
                                        if (angle < pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[6];
                                            StartDrag(contact, selectedSlotIndex, 2);
                                        }
                                        else if (angle > pieAngle && angle < 2 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[7];
                                            StartDrag(contact, selectedSlotIndex, 1);
                                        }
                                        else if (angle > 2 * pieAngle && angle < 3 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[8];
                                            StartDrag(contact, selectedSlotIndex, 0);
                                        }
                                    }

                                    SetActivated(selectedSlotIndex);
                                }
                            }

                            #region PART FOR SLOT 1 UPGRADE DRAGS
                            else if (selectedSlotIndex == 1 && !itemDragged && !itemDeleteDragged)
                            {
                                if (diff.X < 0)
                                {
                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        StartDrag(contact, 1, 0);
                                    }
                                }
                            }
                            #endregion
                        }
                        else
                        {
                            int slotIndex = 4;
                            if (!itemDragged && !itemDeleteDragged && (selectedSlotIndex == -1 || selectedSlotIndex == slotIndex))
                            {
                                // upper left quadrant
                                GetAvailableUpgrades(UpgradeTree.UpgradeRoot,slotIndex);
                                SetUpgradePositions(slotIndex);
                                // if the slot is upgradable, change the view
                                if (HasAvailableUpgrades(slotIndex))
                                {
                                    selectedSlotIndex = slotIndex;
                                    UpgradeTree.SelectedSlot = slotIndex;

                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        if (angle < pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[5];
                                            StartDrag(contact, selectedSlotIndex, 0);
                                        }
                                        else if (angle > pieAngle && angle < 2 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[4];
                                            StartDrag(contact, selectedSlotIndex, 1);
                                        }
                                        else if (angle > 2 * pieAngle && angle < 3 * pieAngle)
                                        {
                                            selectedSlotPos = slotCenterList[3];
                                            StartDrag(contact, selectedSlotIndex, 2);
                                        }
                                    }
                                    SetActivated(selectedSlotIndex);
                                }
                            }

                            #region PART FOR SLOT 0 UPGRADE DRAGS
                            else if (selectedSlotIndex == 0 && !itemDragged && !itemDeleteDragged)
                            {
                                if (diff.X < 0)
                                {
                                    // if it was activated before
                                    if (slotActivated[selectedSlotIndex])
                                    {
                                        StartDrag(contact, 0, 1);
                                    }
                                }
                            }
                            #endregion
                        }
                    }
                }
            }
            // if any slot is selected
            if (selectedSlotIndex != -1)
            {
                // setting description item
                descriptionItem.Visible = true;
                // set at up pos
                if(selectedSlotIndex == 1 || selectedSlotIndex == 2 || selectedSlotIndex == 3)
                {
                    descriptionItem.SetLocationUp(true);
                }
                else
                {
                    descriptionItem.SetLocationUp(false);
                }
                
                for (int i = 0; i < slotUpgradeList.Length; i++)
                {
                    UpgradeNode slotUpgrade = slotUpgradeList[i];

                    // other than the current slot make other current upgrades invisible
                    if (selectedSlotIndex != i && slotUpgrade != null)
                        slotUpgrade.Visible = false;
                }

                if (selectedSlotIndex > 1 && !itemDeleteDragged)
                {
                    // move the current upgrade to center
                    slotUpgradeList[selectedSlotIndex].Position = upgradeCenterList[selectedSlotIndex];
                }

                if (!itemDeleteDragged && !itemDragged)
                {
                    if (Vector2.Distance(new Vector2(backButtonCenter.X, backButtonCenter.Y),
                        new Vector2(contact.CenterX, contact.CenterY)) < 30)
                    {
                        // set all items in preview menu to invisible
                        SetVisible(false);
                        // make the background visible
                        this.Visible = true;
                    }
                }

            }
            else // if the view is at main view (no slot selected)
            {
                SwitchToMainView();
            }
            
        }

        public void TranslateSlots(Vector2 translateVector)
        {
            // update slot center list
            for (int i = 0; i < slotCenterList.Length; i++)
            {
                slotCenterList[i] += translateVector;
            }

            // update upgrades center list
            for (int i = 0; i < upgradeCenterList.Length; i++)
            {
                upgradeCenterList[i] += translateVector;
            }

            // translate available upgrades
            for (int i = 0; i < availableUpgrades.GetLength(1); i++)
            {
                if (selectedSlotIndex != -1)
                {
                    UpgradeNode curnode = availableUpgrades[selectedSlotIndex, i];
                    if (curnode != null)
                        curnode.Position += translateVector;
                }
            }

            // translate upgrades on slots
            for (int i = 0; i < slotUpgradeList.Length; i++)
            {
                UpgradeNode curnode = slotUpgradeList[i];
                if (curnode != null)
                    curnode.Position += translateVector;
            }

            // update collision circles list
            for (int i = 0; i < collisionCircles.Length; i++)
            {
                collisionCircles[i] += translateVector;
            }

            // update slot position list
            for(int i = 0 ; i < quadrantPosList.Length; i++)
            {
                quadrantPosList[i] += translateVector;
            }
            if (selectedSlotPos != Vector2.Zero)
                selectedSlotPos = new Vector2(selectedSlotPos.X + translateVector.X, selectedSlotPos.Y + translateVector.Y);

            backButtonPos += translateVector;
            backButtonCenter += translateVector;
            descriptionItem.Translate(translateVector);
        }
        
        public void RotateSlots(float rotation)
        {
            for (int i = 0; i < slotCenterList.Length; i++)
            {
                slotCenterList[i] = RotatePoint(parent.Position, deltaRotation, slotCenterList[i]);  
            }

            for (int i = 0; i < upgradeCenterList.Length; i++)
            {
                upgradeCenterList[i] = RotatePoint(parent.Position, deltaRotation, upgradeCenterList[i]);
            }

            for (int i = 0; i < quadrantPosList.Length; i++)
            {
                quadrantPosList[i] = RotatePoint(parent.Position, deltaRotation, quadrantPosList[i]);
            }

            // rotate available upgrades
            for (int i = 0; i < availableUpgrades.GetLength(1); i++)
            {
                if (selectedSlotIndex != -1)
                {
                    UpgradeNode curnode = availableUpgrades[selectedSlotIndex, i];
                    if (curnode != null)
                    {
                        curnode.Position = RotatePoint(parent.Position, deltaRotation, curnode.Position);
                        curnode.Rotation += deltaRotation;
                    }
                }
            }

            // rotate current upgrades
            for (int i = 0; i < slotUpgradeList.Length; i++)
            {
                UpgradeNode curnode = slotUpgradeList[i];
                if (curnode != null)
                {
                    curnode.Position = RotatePoint(parent.Position, deltaRotation, curnode.Position);
                    curnode.Rotation += deltaRotation;
                }
            }

            // update collision circles list
            for (int i = 0; i < collisionCircles.Length; i++)
            {
                collisionCircles[i] = RotatePoint(parent.Position, deltaRotation, collisionCircles[i]);
            }
            if(selectedSlotPos != Vector2.Zero)
                selectedSlotPos = RotatePoint(parent.Position, deltaRotation, selectedSlotPos);

            backButtonPos = RotatePoint(parent.Position, deltaRotation, backButtonPos);
            backButtonCenter = RotatePoint(parent.Position, deltaRotation, backButtonCenter);
         
            descriptionItem.Rotate(deltaRotation);
            
        }

        public void UpdateBuildProcess()
        {
            Slot aSlot;
            if (selectedSlotIndex != -1)
            {
                aSlot = CurTower.Slots[selectedSlotIndex];
                // if an upgrade is currently being built
                if (aSlot.Building)
                {
                    completionPercentage = aSlot.completion();
                    byte R = 255;
                    byte B = (byte)(0 + (completionPercentage * 175) );
                    byte G = (byte)(0 + (completionPercentage * 175) );

                    quadColor = new Color(R,G ,B, 255);
                }
                else
                    quadColor = Color.White;
            }
        }

        public bool HasAvailableUpgrades(int slotIndex)
        {
            for (int i = 0; i < availableUpgrades.GetLength(1); i++)
            {
                if (availableUpgrades[slotIndex, i] != null)
                {
                    return true;
                }
            }
            return false;
        }

        public void SetActivated(int index)
        {
            // make rest unactivated
            for (int i = 0; i < slotActivated.Length; i++)
                slotActivated[i] = false;

            slotActivated[index] = true;
        }

        public void SetUpgradePositions(int slotIndex)
        {
            if (availableUpgrades != null)
            {
                int indexInc = 0;
                for (int i = 0; i < availableUpgrades.GetLength(1); i++)
                {
                    UpgradeNode curNode = availableUpgrades[slotIndex,i];
                    if (curNode != null)
                    {
                        if (slotIndex > 1)
                        {
                            availableUpgrades[slotIndex, i].Position = slotCenterList.ElementAt((numberOfSlots - 1) - ((slotIndex - 2) * 3) - indexInc);
                        }
                        else
                        {
                            // slot 0 and slot 1 can have only 2 upgrades max
                            if (i < 2)
                            {
                                availableUpgrades[slotIndex, i].Position = slotCenterList.ElementAt((slotIndex * 6) + indexInc + 1);
                                indexInc += 2;
                            }
                        }
                    }
                    indexInc++;
                }
            }
        }

        public void GetAvailableUpgrades(UpgradeNode rootNode, int slotIndex)
        {
            UpgradeNode curUpgrade = slotUpgradeList[slotIndex];

            if (curUpgrade != null)
            {
                List<UpgradeNode> list = UpgradeTree.GetAvailableUpgrades(rootNode,curUpgrade.Name);
                if(list != null)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        UpgradeNode oldNode = availableUpgrades[slotIndex, i];
                        if (oldNode != null)
                        {
                            oldNode.Kill();
                            oldNode = null;
                        }
                        availableUpgrades[slotIndex, i] = list.ElementAt(i);
                        availableUpgrades[slotIndex, i].Visible = true;
                    }        
                }
            }
            // if the upgrade slot is empty , get first level updates
            else
            {
                List<UpgradeNode> list = UpgradeTree.GetRootUpgrades(rootNode);
                if (list != null)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        UpgradeNode oldNode = availableUpgrades[slotIndex, i];
                        if (oldNode != null)
                        {
                            oldNode.Kill();
                            oldNode = null;
                        }
                        availableUpgrades[slotIndex, i] = list.ElementAt(i);
                    }
                }

                slotUpgradeList[slotIndex] = rootNode;
            }
        }

        public void DragUpgrades(Vector2 contactPoint, Contact aContact)
        {
            if (dragItemContact != null && draggedItem != null)
            {
                draggedItem.Position = new Vector2(aContact.X,aContact.Y);
            }  
        }

        public void DragDeleteUpgrade(Vector2 contactPoint, Contact aContact)
        {
            if (dragDeleteItemContact != null && draggedDeleteItem != null)
            {
                draggedDeleteItem.Position = new Vector2(aContact.X, aContact.Y);
            }
        }

        public void CheckDragFinished()
        {
            if (dragItemContact != null && draggedItem != null)
            {
                Contact tempcontact;
                if (!(((WorldPropertiesSurf)worldProperties).Contacts.TryGetContactFromId(DragItemContact.Id, out tempcontact)))
                {
                    bool collisionCheck = false;
                    // form slots 0 and 1
                    if (selectedSlotIndex  ==  0)
                    {
                        collisionCheck = (Vector2.Distance(new Vector2(draggedItem.Position.X, draggedItem.Position.Y), collisionCircles[3]) < colcircleRadius)
                                            || (Vector2.Distance(new Vector2(draggedItem.Position.X, draggedItem.Position.Y), collisionCircles[2]) < colcircleRadius);
                    }
                    else if(selectedSlotIndex == 1)
                    {
                        collisionCheck = (Vector2.Distance(new Vector2(draggedItem.Position.X, draggedItem.Position.Y), collisionCircles[1]) < colcircleRadius)
                                            || (Vector2.Distance(new Vector2(draggedItem.Position.X, draggedItem.Position.Y), collisionCircles[0]) < colcircleRadius);
                    }
                    else
                    {
                        collisionCheck = (Vector2.Distance(new Vector2(draggedItem.Position.X, draggedItem.Position.Y), collisionCircles[draggedItemSlot - 2]) < colcircleRadius);
                    }
                    if (collisionCheck && !CurTower.Slots[selectedSlotIndex].Building)
                    {
                        // make the change on the preview tower
                        UpgradeNode dragNode = draggedItem;
                        UpgradeNode newNode;
                        if (selectedSlotIndex > 1)
                        {
                            newNode = new UpgradeNode(worldProperties, dragNode.Kind, dragNode.Name, dragNode.Description, dragNode.Sprite, slotCenterList[(numberOfSlots - 1) - ((selectedSlotIndex - 2) * 3) - 1], dragNode.ChildUpgrades);
                        }
                        else
                        {
                            newNode = new UpgradeNode(worldProperties, dragNode.Kind, dragNode.Name, dragNode.Description, dragNode.Sprite, upgradeCenterList[selectedSlotIndex], dragNode.ChildUpgrades);
                        }
                        
                        
                        UpgradeNode oldNode = slotUpgradeList[draggedItemSlot];
                        if (oldNode != null)
                        {
                            oldNode.Kill();
                            oldNode = null;
                        }
                        slotUpgradeList[draggedItemSlot] = newNode;

                        // upgrade on the tower itself
                        CurTower.upgradeSlot(selectedSlotIndex, draggedItem.Kind);

                        for (int i = 0; i < availableUpgrades.GetLength(1); i++)
                        {
                            UpgradeNode aNode = availableUpgrades[selectedSlotIndex, i];
                            if (aNode != null)
                            {
                                aNode.Kill();
                                aNode = null;
                            }
                        }

                        // stop dragging
                        itemDragged = false;
                        draggedItem.Kill();
                        draggedItem = null;
                        dragItemContact = null;
                        selectedSlotIndex = -1; // to switch to view back to previewTower view

                        for (int i = 0; i < slotUpgradeList.Length; i++)
                        {
                            UpgradeNode slotUpgrade = slotUpgradeList[i];
                            if (slotUpgrade != null)
                                slotUpgrade.Visible = true;
                        }

                        descriptionItem.Visible = false;
                    }

                    else
                    {
                        itemDragged = false;
                        draggedItem.Position = dragItemPrePos;
                        dragItemContact = null;
                    }
                }
            }
        }

        public void CheckDeleteDragFinished()
        {
            if (dragDeleteItemContact != null && draggedDeleteItem != null)
            {
                Contact tempcontact;
                if (!(((WorldPropertiesSurf)worldProperties).Contacts.TryGetContactFromId(dragDeleteItemContact.Id, out tempcontact)))
                {
                    bool collisionCheck = false;
                    // form slots 0 and 1
                    if (selectedSlotIndex == 0)
                    {
                        collisionCheck = !(Vector2.Distance(new Vector2(draggedDeleteItem.Position.X, draggedDeleteItem.Position.Y), collisionCircles[3]) < colcircleRadius)
                                            && !(Vector2.Distance(new Vector2(draggedDeleteItem.Position.X, draggedDeleteItem.Position.Y), collisionCircles[2]) < colcircleRadius)
                                            && !(Vector2.Distance(new Vector2(draggedDeleteItem.Position.X, draggedDeleteItem.Position.Y), collisionCircles[4]) < colcircleRadius);
                    }
                    else if (selectedSlotIndex == 1)
                    {
                        collisionCheck = !(Vector2.Distance(new Vector2(draggedDeleteItem.Position.X, draggedDeleteItem.Position.Y), collisionCircles[1]) < colcircleRadius)
                                            && !(Vector2.Distance(new Vector2(draggedDeleteItem.Position.X, draggedDeleteItem.Position.Y), collisionCircles[0]) < colcircleRadius)
                                            && !(Vector2.Distance(new Vector2(draggedDeleteItem.Position.X, draggedDeleteItem.Position.Y), collisionCircles[5]) < colcircleRadius);
                    }
                    else
                    {
                        collisionCheck = !(Vector2.Distance(new Vector2(draggedDeleteItem.Position.X, draggedDeleteItem.Position.Y), collisionCircles[selectedSlotIndex - 2]) < colcircleRadius);
                    }
                    if (collisionCheck)
                    // if it is outside the collision circle
                    {
                        // stop dragging
                        itemDeleteDragged = false;
                        draggedDeleteItem.Kill();
                        draggedDeleteItem = null;
                        dragDeleteItemContact = null;

                        UpgradeNode newRootNode = null;
                        if (selectedSlotIndex > 1)
                        {
                            newRootNode = UpgradeTree.UpgradeRoot;
                            newRootNode.Position = slotCenterList[(numberOfSlots - 1) - ((selectedSlotIndex - 2) * 3) - 1];
                        }
                        else
                        {
                            if (selectedSlotIndex == 0)
                            {
                                newRootNode = UpgradeTree.MainWeaponNode;
                            }
                            else if (selectedSlotIndex == 1)
                            {
                                newRootNode = UpgradeTree.EnergyTransferNode;
                            }

                            if(newRootNode != null)
                               newRootNode.Position =  upgradeCenterList[selectedSlotIndex];
                        }
                        slotUpgradeList[selectedSlotIndex] = newRootNode;

                        // upgrade on the tower itself
                        CurTower.upgradeSlot(selectedSlotIndex, SlotKind.Empty);

                        // clear available upgrades
                        for (int i = 0; i < availableUpgrades.GetLength(1); i++)
                        {
                            UpgradeNode aNode = availableUpgrades[selectedSlotIndex, i];
                            if (aNode != null)
                            {
                                aNode.Kill();
                                aNode = null;
                            }
                        }

                        // prepare for the main view
                        for (int i = 0; i < slotUpgradeList.Length; i++)
                        {
                            UpgradeNode slotUpgrade = slotUpgradeList[i];
                            if (slotUpgrade != null)
                                slotUpgrade.Visible = true;
                        }

                        descriptionItem.Visible = false;
                        selectedSlotIndex = -1; // to switch to view back to previewTower view
                    }
                    else
                    {
                        itemDeleteDragged = false;
                        draggedDeleteItem.Position = dragItemPrePos;
                        dragDeleteItemContact = null;
                    }
                } 
            }
        }

        public void StartDrag(Contact aContact,int slotIndex, int slotOrder)
        {
            //List<int> ownedContactList = ((WorldPropertiesSurf)worldProperties).Owned;
            // check if it's already being used
            //if (!ownedContactList.Contains(aContact.Id))
            //{
                //ownedContactList.Add(aContact.Id);
                UpgradeNode curNode = availableUpgrades[slotIndex, slotOrder];
                if (curNode != null)
                {
                    // start dragging
                    itemDragged = true;
                    draggedItemSlot = slotIndex;
                    draggedItem = curNode;
                    dragItemContact = aContact;
                    dragItemPrePos = curNode.Position;
                    descriptionItem.Text = draggedItem.Description;
                }
            //}
        }

        public void StartDeleteDrag(Contact aContact,int slotIndex)
        {
                UpgradeNode curNode = slotUpgradeList[slotIndex];
                if (curNode != null && curNode.Name != "Root")
                {
                    // start dragging
                    itemDeleteDragged = true;
                    draggedDeleteItem = curNode;
                    dragDeleteItemContact = aContact;
                    dragItemPrePos = curNode.Position;
                    descriptionItem.Text = draggedDeleteItem.Description;
                }
        }

        public void SwitchToMainView()
        {
            for (int i = 0; i < slotUpgradeList.Length; i++)
            {
                UpgradeNode slotUpgrade = slotUpgradeList[i];
                if (slotUpgrade != null)
                    slotUpgrade.Visible = true;
            }

            for (int i = 0; i < slotUpgradeList.Length; i++)
            {
                // move all to main view positions
                if (i > 1 && selectedSlotIndex != -1)
                {
                    //2nd of the outer circle slots 
                    slotUpgradeList[i].Position = slotCenterList[(numberOfSlots - 1) - ((i - 2) * 3) - 1];
                }
            }

            descriptionItem.Visible = false;
        }

        public void SetVisible(bool visible)
        {
                this.Visible = visible;
                // make it invisible
                if (!visible)
                {
                    if (selectedSlotIndex != -1)
                    {
                        for (int i = 0; i < availableUpgrades.GetLength(1); i++)
                        {
                            // kill available upgrades so they are invisible
                            UpgradeNode aNode = availableUpgrades[selectedSlotIndex, i];
                            if (aNode != null)
                            {
                                aNode.Kill();
                                aNode = null;
                            }
                        }

                        
                        for (int i = 0; i < slotUpgradeList.Length; i++)
                        {
                            // move all to main view positions
                            if (i > 1)
                            {
                                slotUpgradeList[i].Position = slotCenterList[(numberOfSlots - 1) - ((i - 2) * 3) - 1];
                            }
                            else
                            {
                                slotUpgradeList[i].Position = upgradeCenterList[i];
                            }

                        }

                        descriptionItem.Visible = false;
                        selectedSlotIndex = -1;
                    }

                    for (int i = 0; i < slotUpgradeList.Length; i++)
                    {
                        UpgradeNode slotUpgrade = slotUpgradeList[i];
                        if (slotUpgrade != null)
                        {
                            slotUpgrade.Visible = false;
                        }
                    }
                }
                else // if it becomes visible
                {
                    for (int i = 0; i < slotUpgradeList.Length; i++)
                    {
                        UpgradeNode slotUpgrade = slotUpgradeList[i];
                        if (slotUpgrade != null)
                        {
                            slotUpgrade.Visible = true;
                        }
                    }
                }

        }
    }
}
